package network;

public class Message implements Cloneable{

	
	public static final byte DELIMITER = 73;
	public static final byte PADDING = 3;
	public static final String PAD = ""+((char)PADDING)+((char)PADDING)+((char)PADDING)+((char)PADDING);
	
	
		/*
		 *Connection_msg
		 *Messages for connecting + disconnecting.
		 * 
		 * Text_msg
		 * sending text, like user communications back + forth.
		 * 
		 * change_name
		 * user request to change name
		 * 
		 * leave_msg
		 * user saying they're leaving
		 * 
		 * request_msg
		 * usr requesting something from the server
		 * ei: member list
		 * 
		 * pings (ping send)
		 * ping from here to connection
		 * Sent when pinging someone, we will send them.
		 * And others will send them to us.
		 * 
		 * pingr (ping return)
		 * ping from connection to here
		 * When we ping, we will get these types back.
		 * And we will send these types back when people ping us.
		 * 
		 * REDUND
		 * request for redundant servers for this server, in case we go down.
		 * we send this list to our connections
		 * 
		 * S_REDUND
		 * request for redundant servers for the server we are sending it to.
		 * In case they go down, (they will send a 'REDUND' to their server)
		 * 
		 * undefined_type
		 * none of the above.
		 * 
		 * 
		 */
		
	public static final byte CONNECTION_MSG = 0;
	public static final byte TEXT_MSG = 1;
	public static final byte PINGS = 2;
	public static final byte PINGR = 3;
	public static final byte KEEP_ALIVE = 4;
	public static final byte S_REDUND = 5;
	public static final byte REDUND = 6;
	public static final byte INFO = 7;
	
		
	public void setType(byte b){
		type = -1;
		if( -1 < b && b < 8){
			type = b;
		}
	}
	
	private String text = null;
	private byte type = TEXT_MSG;
	
	public Connection orig=null;
	
	public Message(){
	
	}
	
	
	public Message(int i, String str){
		text = str;
		type = (byte)i;
	}
	
	public Message(String str){
		this((byte)-1,str);
	}
	
	public void setOrig(Connection c){
		if(orig == null){
			orig = c;
		}
	}
	
	public void setText(String str){
		text = str;
	} 
	public String getText(){
		return text;
	}
	public byte getType(){
		return type;
	}
	
	@Override
	public Object clone(){
		Message ret = new Message();
		ret.text = this.text;
		ret.type = this.type;
		return ret;
	}
	
	
	
	/**
	 * This method takes a String generated by convertMessage(Message m) and turns it back into a Message object. 
	 * @param str the message you want parsed into a message object.
	 * @return returns a Message object.
	 * @throws MessageFormatException if the string isn't in message format.
	 */
	public static Message parseMessage(String str) throws MessageFormatException{
		String ret = null;
		if(str.length() < 9){
			//this is the min message length, 4 buffer 0 on each end + type.
			throw new MessageFormatException("Message '"+str+"' too short.");
		}
		for(int i=0; i<4; i++){//check the first 4 characters
			if(str.charAt(i) != PADDING){
				throw MessageFormatException.forString(str);
			}
		}
		for(int i=str.length()-4; i<str.length(); i++){//check the last 4 characters
			if(str.charAt(i) != PADDING){
				throw MessageFormatException.forString(str);
			}
		}
		
		ret = str.substring(5,str.length()-4);
				
		return new Message((byte)str.charAt(4),ret);
	}
	
	/**
	 * turns Message m into a String, the String is parsable by parseMessage(String str)
	 * @param m Message to convert
	 * @return returns Message in string form.
	 */
	public static String convertMessage(Message m){
		String ret = "";
		
		ret = PAD+((char)m.getType());
		
		ret = ret + m.getText();
		
		ret = ret +PAD;
		
		return ret;
	}

	
}
